package consul.allinone.discovery;

import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.orbitz.consul.Consul;
import com.orbitz.consul.HealthClient;
import com.orbitz.consul.cache.ConsulCache;
import com.orbitz.consul.cache.ServiceHealthCache;
import com.orbitz.consul.cache.ServiceHealthKey;
import com.orbitz.consul.model.ConsulResponse;
import com.orbitz.consul.model.health.ServiceHealth;
import consul.allinone.RpcURL;
import consul.allinone.regist.AbstractConsulService;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Title:
 * Description:
 * Author:吉
 * Since:2018/4/13
 * Version:1.1.0
 */
public class ConsulSubscirbeService extends AbstractConsulService implements SubscirbeService {


    @Override
    public void subscribe(String registryHost, int registryPort, String serviceName) {
        Consul consul = this.buildConsul(registryHost, registryPort);
        HealthClient client = consul.healthClient();
        watch(client, serviceName);
    }

    @Override
    public List<RpcURL> listServices() {
        return RpcClientInvokerCache.getConnectedHandlersClone();
    }

    private void watch(HealthClient healthClient, String serviceName) {
        try {
            ServiceHealthCache serviceHealthCache = ServiceHealthCache.newCache(healthClient, serviceName);
            serviceHealthCache.addListener(new ConsulCache.Listener<ServiceHealthKey, ServiceHealth>() {
                @Override
                public void notify(Map<ServiceHealthKey, ServiceHealth> map) {
                    System.out.println(new Gson().toJson(map));
                    RpcClientInvokerCache.clear();
                    ConsulResponse<List<ServiceHealth>> object = healthClient.getHealthyServiceInstances(serviceName);
                    List<ServiceHealth> serviceHealths = object.getResponse();
                    for (ServiceHealth serviceHealth : serviceHealths) {
                        RpcURL url = new RpcURL(serviceHealth.getService().getAddress(), serviceHealth.getService().getPort());
                        url.setServiceName(serviceHealth.getService().getService());
                        url.setId(serviceHealth.getService().getId());
                        RpcClientInvokerCache.addHandler(url);
                    }
                }
            });
            serviceHealthCache.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
